package com.smmisia.shop.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smmisia.common.Result.Result;
import com.smmisia.shop.entity.Ticket;
import com.smmisia.shop.entity.TicketOrder;
import com.smmisia.shop.entity.TicketSchedule;
import com.smmisia.shop.entity.convetor.TicketConvertor;
import com.smmisia.shop.entity.convetor.TicketOrderConvertor;
import com.smmisia.shop.enums.ComboEnum;
import com.smmisia.shop.enums.EnterStatusEnum;
import com.smmisia.shop.enums.TicketOrderEnum;
import com.smmisia.shop.enums.TicketTypeEnum;
import com.smmisia.shop.exception.ProductException;
import com.smmisia.shop.mapper.TicketOrderMapper;
import com.smmisia.shop.mapper.TicketScheduleMapper;
import com.smmisia.shop.request.TicketBuyResponse;
import com.smmisia.shop.request.TicketRequest;
import com.smmisia.shop.response.TicketOrderResponse;
import com.smmisia.shop.response.TicketResponse;
import com.smmisia.shop.response.dto.ComboTicketDTO;
import com.smmisia.shop.response.dto.TicketDTO;
import com.smmisia.shop.service.TicketService;
import com.smmisia.shop.mapper.TicketMapper;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


@Service
public class TicketServiceImpl extends ServiceImpl<TicketMapper, Ticket>
        implements TicketService {

    @Autowired
    private TicketMapper ticketMapper;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private TicketScheduleMapper ticketScheduleMapper;

    @Autowired
    private TicketOrderMapper ticketOrderMapper;

    @Override
    public Result<TicketResponse> getTicketList(Integer scenicSpotId) {
        List<Ticket> list = ticketMapper.selectList(Wrappers.lambdaQuery(Ticket.class)
                .eq(Ticket::getScenicSpotId, scenicSpotId)
                .eq(Ticket::getType, TicketTypeEnum.SCENIC_AREA_TICKET.getCode()));
        List<TicketDTO> ticketDTO = new ArrayList<>();
        List<ComboTicketDTO> comboTicketDTO = new ArrayList<>();
        list.stream().forEach(ticket -> {
            if (ticket.getComboStatus() == ComboEnum.SINGLE_TICKET) {
                TicketDTO dto = TicketConvertor.INSTANCE.toDTO(ticket);
                ticketDTO.add(dto);
            } else {
                ComboTicketDTO comboDTO = TicketConvertor.INSTANCE.toComboDTO(ticket);
                comboTicketDTO.add(comboDTO);
            }
        });
        TicketResponse ticketResponse = new TicketResponse();
        ticketResponse.setComboTicket(comboTicketDTO);
        ticketResponse.setTicket(ticketDTO);
        return Result.ok(ticketResponse);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<TicketBuyResponse> buyTicket(TicketRequest request) {
        Integer ticketId = request.getTicketId();
        RLock lock = redissonClient.getLock("ticket:" + ticketId);
        boolean isLocked = false;

        try {
            // 尝试获取分布式锁
            isLocked = lock.tryLock(3, 30, TimeUnit.SECONDS);
            if (!isLocked) {
                return Result.fail("系统繁忙，请稍后重试");
            }

            // 查询并检查票务信息
            Ticket ticket = ticketMapper.selectById(ticketId);
            if (ticket == null) {
                return Result.fail("票务信息不存在");
            }
            if (ticket.getCount() <= 0) {
                return Result.fail("票务已售罄");
            }

            // 扣减库存
            if (ticketMapper.decrease(ticketId) != 1) {
                return Result.fail("购票失败，库存不足");
            }

            // 创建订单
            TicketOrder ticketOrder = TicketOrder.builder()
                    .ticketId(ticketId)
                    .orderId(generateOrderId(ticketId))
                    .userId(StpUtil.getLoginIdAsInt())
                    .status(TicketOrderEnum.TICKET_ORDER_NOT_PAY)
                    .createTime(request.getBuyTime())
                    .build();

            ticketOrderMapper.insert(ticketOrder);
            TicketBuyResponse response = new TicketBuyResponse();
            response.setOrderId(ticketOrder.getOrderId());
            return Result.ok(response);
        } catch (Exception e) {
            log.error("购票异常", e);
            throw new RuntimeException("购票失败");
        } finally {
            if (isLocked) {
                lock.unlock();
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Boolean> buyTicketScheduled(TicketRequest request) {
        Integer ticketId = request.getTicketId();
        RLock lock = redissonClient.getLock("ticketSchedule:" + ticketId);
        boolean isLocked = false;

        try {
            // 尝试获取分布式锁
            isLocked = lock.tryLock(3, 30, TimeUnit.SECONDS);
            if (!isLocked) {
                return Result.fail("系统繁忙，请稍后重试");
            }

            // 查询并检查票务信息
            TicketSchedule ticket = ticketScheduleMapper.selectById(ticketId);
            if (ticket == null) {
                return Result.fail("票务信息不存在");
            }
            if (ticket.getCount() <= 0) {
                return Result.fail("票务已售罄");
            }

            // 扣减库存
            if (ticketMapper.decrease(ticketId) != 1) {
                return Result.fail("购票失败，库存不足");
            }

            // 创建订单
            TicketOrder ticketOrder = TicketOrder.builder()
                    .ticketId(ticketId)
                    .orderId(generateOrderId(ticketId))
                    .userId(StpUtil.getLoginIdAsInt())
                    .createTime(request.getBuyTime())
                    .build();

            ticketOrderMapper.insert(ticketOrder);
            return Result.ok(true);
        } catch (Exception e) {
            log.error("购票异常", e);
            throw new RuntimeException("购票失败");
        } finally {
            if (isLocked) {
                lock.unlock();
            }
        }
    }

    @Override
    public Result<List<TicketOrderResponse>> getTicket() {
        List<TicketOrder> orderList = ticketOrderMapper.selectList(Wrappers.lambdaQuery(TicketOrder.class)
                .eq(TicketOrder::getUserId, StpUtil.getLoginIdAsInt()));

        List<Integer> ticketIds = orderList.stream()
                .map(TicketOrder::getTicketId)
                .collect(Collectors.toList());


        List<Ticket> tickets = ticketIds.isEmpty() ? Collections.emptyList()
                : ticketMapper.selectBatchIds(ticketIds);


        Map<Integer, TicketDTO> ticketMap = tickets.stream()
                .map(TicketConvertor.INSTANCE::toDTO)
                .collect(Collectors.toMap(TicketDTO::getId, dto -> dto));


        return Result.ok(orderList.stream()
                .map(order -> {
                    TicketOrderResponse response = TicketOrderConvertor.INSTANCE.toRes(order);
                    response.setTicketInfo(ticketMap.get(order.getTicketId()));
                    return response;
                })
                .collect(Collectors.toList()));
    }

    @Override
    public Result<Boolean> cancelTicketOrder(Integer orderId) {
        TicketOrder ticketOrder = ticketOrderMapper.selectOne(Wrappers.lambdaQuery(TicketOrder.class).eq(TicketOrder::getOrderId,orderId));
        if (ticketOrder == null) {
            return Result.fail("订单不存在");
        }
        ticketOrder.setStatus(TicketOrderEnum.TICKET_ORDER_CANCEL);
        if(ticketOrderMapper.updateById(ticketOrder)!=1){
            return Result.fail("订单取消失败");
        }
        int row = ticketMapper.increase(ticketOrder.getTicketId());
        return Result.ok("订单取消成功");
    }

    @Override
    public Result<Boolean> payTicketOrder(Integer orderId) {
        TicketOrder ticketOrder = ticketOrderMapper.selectOne(Wrappers.lambdaQuery(TicketOrder.class).eq(TicketOrder::getOrderId,orderId));
        if (ticketOrder == null) {
            return Result.fail("订单不存在");
        }
        ticketOrder.setStatus(TicketOrderEnum.TICKET_ORDER_PAY);
        if(ticketOrderMapper.updateById(ticketOrder)!=1){
            return Result.fail("订单支付失败");
        }
        return Result.ok("订单支付成功");
    }

    @Override
    public Result<TicketOrderResponse> getTicketById(Integer orderId) {
        TicketOrder ticketOrder = ticketOrderMapper.selectOne(Wrappers.lambdaQuery(TicketOrder.class).eq(TicketOrder::getOrderId,orderId));
        TicketOrderResponse response = TicketOrderConvertor.INSTANCE.toRes(ticketOrder);
        Ticket ticket = ticketMapper.selectById(ticketOrder.getTicketId());
        response.setPrice(ticket.getSalePrice());
        return Result.ok(response);
    }

    private Integer generateOrderId(Integer ticketId) {
        return (int) System.currentTimeMillis() + ticketId + StpUtil.getLoginIdAsInt();
    }


}




